home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / twnsck12.zip / SRC\PACKET.C < prev    next >
Text File  |  1994-12-03  |  16KB  |  642 lines

  1. /*
  2.  *  TwinSock - "Troy's Windows Sockets"
  3.  *
  4.  *  Copyright (C) 1994  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include <stdio.h>
  22. #ifdef __MSDOS__
  23. #include <winsock.h>
  24. #include <stdlib.h>
  25. #else
  26. #include <sys/types.h>
  27. #include <netinet/in.h>
  28. #endif
  29. #include "packet.h"
  30.  
  31. #define    MAX_STREAMS    256
  32. #define    WINDOW_SIZE    4
  33.  
  34. short    nInSeq = 0;
  35. short    nOutSeq = 0;
  36.  
  37. extern    int    SendData(void    *pvData, int nBytes);
  38.  
  39. static unsigned long crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
  40. 0x00000000l, 0x77073096l, 0xee0e612cl, 0x990951bal, 0x076dc419l, 0x706af48fl, 0xe963a535l, 0x9e6495a3l,
  41. 0x0edb8832l, 0x79dcb8a4l, 0xe0d5e91el, 0x97d2d988l, 0x09b64c2bl, 0x7eb17cbdl, 0xe7b82d07l, 0x90bf1d91l,
  42. 0x1db71064l, 0x6ab020f2l, 0xf3b97148l, 0x84be41del, 0x1adad47dl, 0x6ddde4ebl, 0xf4d4b551l, 0x83d385c7l,
  43. 0x136c9856l, 0x646ba8c0l, 0xfd62f97al, 0x8a65c9ecl, 0x14015c4fl, 0x63066cd9l, 0xfa0f3d63l, 0x8d080df5l,
  44. 0x3b6e20c8l, 0x4c69105el, 0xd56041e4l, 0xa2677172l, 0x3c03e4d1l, 0x4b04d447l, 0xd20d85fdl, 0xa50ab56bl,
  45. 0x35b5a8fal, 0x42b2986cl, 0xdbbbc9d6l, 0xacbcf940l, 0x32d86ce3l, 0x45df5c75l, 0xdcd60dcfl, 0xabd13d59l,
  46. 0x26d930acl, 0x51de003al, 0xc8d75180l, 0xbfd06116l, 0x21b4f4b5l, 0x56b3c423l, 0xcfba9599l, 0xb8bda50fl,
  47. 0x2802b89el, 0x5f058808l, 0xc60cd9b2l, 0xb10be924l, 0x2f6f7c87l, 0x58684c11l, 0xc1611dabl, 0xb6662d3dl,
  48. 0x76dc4190l, 0x01db7106l, 0x98d220bcl, 0xefd5102al, 0x71b18589l, 0x06b6b51fl, 0x9fbfe4a5l, 0xe8b8d433l,
  49. 0x7807c9a2l, 0x0f00f934l, 0x9609a88el, 0xe10e9818l, 0x7f6a0dbbl, 0x086d3d2dl, 0x91646c97l, 0xe6635c01l,
  50. 0x6b6b51f4l, 0x1c6c6162l, 0x856530d8l, 0xf262004el, 0x6c0695edl, 0x1b01a57bl, 0x8208f4c1l, 0xf50fc457l,
  51. 0x65b0d9c6l, 0x12b7e950l, 0x8bbeb8eal, 0xfcb9887cl, 0x62dd1ddfl, 0x15da2d49l, 0x8cd37cf3l, 0xfbd44c65l,
  52. 0x4db26158l, 0x3ab551cel, 0xa3bc0074l, 0xd4bb30e2l, 0x4adfa541l, 0x3dd895d7l, 0xa4d1c46dl, 0xd3d6f4fbl,
  53. 0x4369e96al, 0x346ed9fcl, 0xad678846l, 0xda60b8d0l, 0x44042d73l, 0x33031de5l, 0xaa0a4c5fl, 0xdd0d7cc9l,
  54. 0x5005713cl, 0x270241aal, 0xbe0b1010l, 0xc90c2086l, 0x5768b525l, 0x206f85b3l, 0xb966d409l, 0xce61e49fl,
  55. 0x5edef90el, 0x29d9c998l, 0xb0d09822l, 0xc7d7a8b4l, 0x59b33d17l, 0x2eb40d81l, 0xb7bd5c3bl, 0xc0ba6cadl,
  56. 0xedb88320l, 0x9abfb3b6l, 0x03b6e20cl, 0x74b1d29al, 0xead54739l, 0x9dd277afl, 0x04db2615l, 0x73dc1683l,
  57. 0xe3630b12l, 0x94643b84l, 0x0d6d6a3el, 0x7a6a5aa8l, 0xe40ecf0bl, 0x9309ff9dl, 0x0a00ae27l, 0x7d079eb1l,
  58. 0xf00f9344l, 0x8708a3d2l, 0x1e01f268l, 0x6906c2fel, 0xf762575dl, 0x806567cbl, 0x196c3671l, 0x6e6b06e7l,
  59. 0xfed41b76l, 0x89d32be0l, 0x10da7a5al, 0x67dd4accl, 0xf9b9df6fl, 0x8ebeeff9l, 0x17b7be43l, 0x60b08ed5l,
  60. 0xd6d6a3e8l, 0xa1d1937el, 0x38d8c2c4l, 0x4fdff252l, 0xd1bb67f1l, 0xa6bc5767l, 0x3fb506ddl, 0x48b2364bl,
  61. 0xd80d2bdal, 0xaf0a1b4cl, 0x36034af6l, 0x41047a60l, 0xdf60efc3l, 0xa867df55l, 0x316e8eefl, 0x4669be79l,
  62. 0xcb61b38cl, 0xbc66831al, 0x256fd2a0l, 0x5268e236l, 0xcc0c7795l, 0xbb0b4703l, 0x220216b9l, 0x5505262fl,
  63. 0xc5ba3bbel, 0xb2bd0b28l, 0x2bb45a92l, 0x5cb36a04l, 0xc2d7ffa7l, 0xb5d0cf31l, 0x2cd99e8bl, 0x5bdeae1dl,
  64. 0x9b64c2b0l, 0xec63f226l, 0x756aa39cl, 0x026d930al, 0x9c0906a9l, 0xeb0e363fl, 0x72076785l, 0x05005713l,
  65. 0x95bf4a82l, 0xe2b87a14l, 0x7bb12bael, 0x0cb61b38l, 0x92d28e9bl, 0xe5d5be0dl, 0x7cdcefb7l, 0x0bdbdf21l,
  66. 0x86d3d2d4l, 0xf1d4e242l, 0x68ddb3f8l, 0x1fda836el, 0x81be16cdl, 0xf6b9265bl, 0x6fb077e1l, 0x18b74777l,
  67. 0x88085ae6l, 0xff0f6a70l, 0x66063bcal, 0x11010b5cl, 0x8f659effl, 0xf862ae69l, 0x616bffd3l, 0x166ccf45l,
  68. 0xa00ae278l, 0xd70dd2eel, 0x4e048354l, 0x3903b3c2l, 0xa7672661l, 0xd06016f7l, 0x4969474dl, 0x3e6e77dbl,
  69. 0xaed16a4al, 0xd9d65adcl, 0x40df0b66l, 0x37d83bf0l, 0xa9bcae53l, 0xdebb9ec5l, 0x47b2cf7fl, 0x30b5ffe9l,
  70. 0xbdbdf21cl, 0xcabac28al, 0x53b39330l, 0x24b4a3a6l, 0xbad03605l, 0xcdd70693l, 0x54de5729l, 0x23d967bfl,
  71. 0xb3667a2el, 0xc4614ab8l, 0x5d681b02l, 0x2a6f2b94l, 0xb40bbe37l, 0xc30c8ea1l, 0x5a05df1bl, 0x2d02ef8dl
  72. };
  73.  
  74. #define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
  75.  
  76. static    short
  77. CalcCRC(data, size)
  78. char *data;
  79. int size;
  80. {
  81.     unsigned long crc = 0xffff;
  82.  
  83.     while (size--)
  84.     {
  85.         crc = UPDC32(*data++, crc);
  86.     }
  87.     crc = ~crc;
  88.     return (crc & 0xffff);
  89. }
  90.  
  91. struct    packet_queue
  92. {
  93.     int            idPacket;
  94.     int            iPacketLen;
  95.     int            iStream;
  96.     int            iFlags;
  97.     struct    packet        *pkt;
  98.     struct    packet_queue    *ppqNext;
  99. };
  100.  
  101. #define    PQF_LEADER    0x0001
  102. #define    PQF_TRAILER    0x0002
  103.  
  104. static    struct    packet_queue *ppqList = 0;
  105. static    int    iInitialised = 0;
  106. static    struct    packet_queue *appqStreams[MAX_STREAMS];
  107. static    struct    packet_queue *ppqSent = 0;
  108. static    int    nSent = 0;
  109. static    struct    packet_queue *ppqReceived = 0;
  110. static    char    aiStreams[MAX_STREAMS / 8];
  111.  
  112. #define    STREAM_BIT(x)    (1 << (((x) + 1) % 8))
  113. #define    STREAM_BYTE(x)    aiStreams[((x) + 1) / 8]
  114.  
  115. #define    SET_STREAM(x)    (STREAM_BYTE(x) |= STREAM_BIT(x))
  116. #define    CLR_STREAM(x)    (STREAM_BYTE(x) &= ~STREAM_BIT(x))
  117. #define    GET_STREAM(x)    ((STREAM_BYTE(x) & STREAM_BIT(x)) != 0)
  118.  
  119. static    char ach6bit[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";
  120.  
  121. void    PoppedPacket(struct packet_queue *ppqPopped);
  122. void    PutInQueue(struct packet_queue *ppq, int iStream);
  123.  
  124. void    InsertInQueue(struct packet_queue **pppqNext, struct packet_queue *ppq)
  125. {
  126.     for (; *pppqNext; pppqNext = &((*pppqNext)->ppqNext));
  127.     *pppqNext = ppq;
  128. }
  129.  
  130. void    FlushQueue(struct packet_queue **pppq)
  131. {
  132.     struct    packet_queue *ppqPop;
  133.  
  134.     while ((ppqPop = *pppq) != 0)
  135.     {
  136.         *pppq = ppqPop->ppqNext;
  137.         free(ppqPop->pkt);
  138.         free(ppqPop);
  139.     }
  140. }
  141.  
  142.  
  143. int    TransmitData(void *pvData, int iDataLen)
  144. {
  145.     char    *pchDataIn;
  146.     char    *pchDataOut;
  147.     char    c;
  148.     int    iIn, iOut;
  149.     int    nBits;
  150.     int    nBitsLeft;
  151.     int    nBitsNow;
  152.     int    nDataOut;
  153.     char    cNow, cTmp;
  154.  
  155.     nDataOut = iDataLen * 4 / 3 + 1;
  156.     if (iDataLen % 6)
  157.         nDataOut++;
  158.     pchDataIn = (char *) pvData;
  159.     pchDataOut = (char *) malloc(nDataOut);
  160.     nBits = nBitsLeft = 0;
  161.     cNow = 0;
  162.     pchDataOut[0] = '@';    /* Signals the receiving end to realign to bit 0 */
  163.     for (iIn = 0, iOut = 1; iOut < nDataOut;)
  164.     {
  165.         if (nBitsLeft)
  166.         {
  167.             cTmp = c & ((1 << nBitsLeft) - 1);
  168.             nBitsNow = 6 - nBits;
  169.             if (nBitsLeft < nBitsNow)
  170.                 nBitsNow = nBitsLeft;
  171.             cNow <<= nBitsNow;
  172.             cTmp >>= nBitsLeft - nBitsNow;
  173.             cTmp &= ((1 << nBitsNow) - 1);
  174.             cNow |= cTmp;
  175.             nBits += nBitsNow;
  176.             nBitsLeft -= nBitsNow;
  177.             if (nBits == 6)
  178.             {
  179.                 pchDataOut[iOut++] = ach6bit[cNow];
  180.                 cNow = 0;
  181.                 nBits = 0;
  182.             }
  183.         }
  184.         else
  185.         {
  186.             if (iIn < iDataLen)
  187.                 c = pchDataIn[iIn++];
  188.             else
  189.                 c = 0;
  190.             nBitsLeft = 8;
  191.         }
  192.     }
  193.     nDataOut =  SendData(pchDataOut, nDataOut);
  194.     free(pchDataOut);
  195.     return nDataOut;
  196. }
  197.  
  198. static    void
  199. TransmitPacket(struct packet_queue *ppqList)
  200. {
  201.     TransmitData(ppqList->pkt, ppqList->iPacketLen);
  202.     SetTransmitTimeout();
  203. }
  204.  
  205. void
  206. InsertIntoIncoming(struct packet *pkt, int iLen)
  207. {
  208.     struct packet_queue *ppq;
  209.     struct packet_queue **pppq;
  210.     struct packet *pktNew;
  211.     int    iPacketID;
  212.  
  213.     iPacketID = ntohs(pkt->iPacketID);
  214.  
  215.     for (    pppq = &ppqReceived;
  216.         *pppq && (*pppq)->idPacket < iPacketID;
  217.         pppq = &(*pppq)->ppqNext);
  218.     if ((*pppq) && (*pppq)->idPacket == iPacketID)
  219.         return;
  220.     pktNew = (struct packet *) malloc(sizeof(struct packet));
  221.     *pktNew = *pkt;
  222.  
  223.     ppq = (struct packet_queue *) malloc(sizeof(struct packet_queue));
  224.     ppq->ppqNext = *pppq;
  225.     ppq->idPacket = iPacketID;
  226.     ppq->pkt = pktNew;
  227.     ppq->iPacketLen = iLen;
  228.     *pppq = ppq;
  229.  
  230.     while (ppqReceived && ppqReceived->idPacket == nInSeq)
  231.     {
  232.         nInSeq++;
  233.         DataReceived(ppqReceived->pkt->achData,
  234.                  ppqReceived->iPacketLen - sizeof(short) * 4);
  235.         ppq = ppqReceived;
  236.         ppqReceived = ppq->ppqNext;
  237.         free(ppq->pkt);
  238.         free(ppq);
  239.     }
  240. }
  241.  
  242.  
  243.  
  244. void    TimeoutReceived(void)
  245. {
  246.     struct    packet_queue *ppq;
  247.  
  248.     for (ppq = ppqSent; ppq; ppq = ppq->ppqNext)
  249.         TransmitPacket(ppq);
  250. }
  251.  
  252. void    InitHead()
  253. {
  254.     struct packet *pkt;
  255.     short    nCRC;
  256.  
  257.     ppqList->idPacket = nOutSeq;
  258.     pkt = ppqList->pkt;
  259.     pkt->iPacketID = htons(nOutSeq);
  260.     nCRC = CalcCRC(pkt, ppqList->iPacketLen);
  261.     pkt->nCRC = htons(nCRC);
  262.     nOutSeq++;
  263. }
  264.  
  265. void    TransmitHead(void)
  266. {
  267.     struct packet_queue *ppq;
  268.  
  269.     if (nSent < WINDOW_SIZE)
  270.     {
  271.         nSent++;
  272.         ppq = ppqList;
  273.         ppqList = ppq->ppqNext;
  274.         ppq->ppqNext = 0;
  275.         InsertInQueue(&ppqSent, ppq);
  276.         PoppedPacket(ppq);
  277.         TransmitPacket(ppq);
  278.     }
  279. }
  280.  
  281. static    void
  282. AckReceived(int id)
  283. {
  284.     struct packet_queue **pppq, *ppqTemp;
  285.  
  286.     for (pppq = &ppqSent;
  287.          *pppq && (*pppq)->idPacket != id;
  288.          pppq = &(*pppq)->ppqNext);
  289.     if (*pppq)
  290.     {
  291.         while (ppqSent != *pppq)
  292.         {
  293.             ppqTemp = ppqSent;
  294.             ppqSent = ppqTemp->ppqNext;
  295.             ppqTemp->ppqNext = 0;
  296.             InsertInQueue(&ppqSent, ppqTemp);
  297.             TransmitPacket(ppqTemp);
  298.         }
  299.         ppqTemp = ppqSent;
  300.         ppqSent = ppqTemp->ppqNext;
  301.         free(ppqTemp->pkt);
  302.         free(ppqTemp);
  303.         nSent--;
  304.         if (ppqList)
  305.             TransmitHead();
  306.         if (!ppqSent)
  307.             KillTransmitTimeout();
  308.     }
  309. }
  310.  
  311.  
  312. void    FlushStream(int    iStream)
  313. {
  314.     FlushQueue(appqStreams + iStream + 1);
  315. }
  316.  
  317. void    PutInQueue(struct packet_queue *ppq, int iStream)
  318. {
  319.     if (iStream == -2) /* Urgent */
  320.     {
  321.         InsertInQueue(&ppqList, ppq);
  322.     }
  323.     else if (GET_STREAM(iStream) && 
  324.          (appqStreams[iStream + 1] ||
  325.           (ppq->iFlags & PQF_LEADER)))
  326.     {
  327.         InsertInQueue(appqStreams + iStream + 1, ppq);
  328.     }
  329.     else
  330.     {
  331.         SET_STREAM(iStream);
  332.         InsertInQueue(&ppqList, ppq);
  333.     }
  334.     if (ppqList == ppq)
  335.     {
  336.         InitHead();
  337.         TransmitHead();
  338.     }
  339. }
  340.  
  341. void    PoppedPacket(struct packet_queue *ppqPopped)
  342. {
  343.     int    iStream, iFlags;
  344.     struct    packet_queue *ppqPop;
  345.  
  346.     iStream = ppqPopped->iStream;
  347.     iFlags = ppqPopped->iFlags;
  348.  
  349.     if (iStream != -2 && (iFlags & PQF_TRAILER))
  350.     {
  351.         if (appqStreams[iStream + 1])
  352.         {
  353.             do
  354.             {
  355.                 ppqPop = appqStreams[iStream + 1];
  356.                 appqStreams[iStream + 1] = ppqPop->ppqNext;
  357.                 ppqPop->ppqNext = 0;
  358.                 InsertInQueue(&ppqList, ppqPop);
  359.             } while (!(ppqPop->iFlags & PQF_TRAILER));
  360.         }
  361.         else
  362.         {
  363.             CLR_STREAM(iStream);
  364.         }
  365.     }
  366.  
  367.     if (ppqList)
  368.     {
  369.         InitHead();
  370.         TransmitHead();
  371.     }
  372. }
  373.  
  374. void    SendPacket(void    *pvData, int iDataLen, int iStream, int iFlags)
  375. {
  376.     struct    packet    *pkt;
  377.     struct    packet_queue *ppq;
  378.     short    nCRC;
  379.  
  380.     if (!iInitialised)
  381.     {
  382.         iInitialised = 1;
  383.         memset(aiStreams, 0, sizeof(aiStreams));
  384.         memset(appqStreams, 0, sizeof(appqStreams));
  385.     }
  386.  
  387.     pkt = (struct packet *) malloc(sizeof(struct packet));
  388.     ppq = (struct packet_queue *) malloc(sizeof(struct packet_queue));
  389.  
  390.     ppq->iPacketLen = iDataLen + sizeof(short) * 4;
  391.     ppq->iStream = iStream;
  392.     ppq->pkt = pkt;
  393.     ppq->ppqNext = 0;
  394.     ppq->iFlags = iFlags;
  395.  
  396.     pkt->iPacketLen = htons(iDataLen);
  397.     pkt->nCRC = 0;
  398.     pkt->nType = htons((short) PT_Data);
  399.     memcpy(pkt->achData, pvData, iDataLen);
  400.  
  401.     PutInQueue(ppq, iStream);
  402. }
  403.  
  404. void    TransmitAck(short id)
  405. {
  406.     struct packet pkt;
  407.     int    nCRC;
  408.  
  409.     pkt.iPacketLen = 0;
  410.     pkt.nCRC = 0;
  411.     pkt.nType = htons((short) PT_Ack);
  412.     pkt.iPacketID = htons(id);
  413.     nCRC = CalcCRC(&pkt, sizeof(short) * 4);
  414.     pkt.nCRC = htons(nCRC);
  415.     TransmitData(&pkt, sizeof(short) * 4);
  416. }
  417.  
  418. void    ProcessData(void *pvData, int nDataLen)
  419. {
  420.     static    struct    packet    pkt;
  421.     static    int    nBytes = 0;
  422.     int        nToCopy;
  423.     int        nData;
  424.     enum packet_type pt;
  425.     short        iLen;
  426.     short        nCRC;
  427.     short        id;
  428.     short        iLocation;
  429.  
  430.     if (!pvData)    /* Receive timeout */
  431.     {
  432.         nBytes = 0;
  433.         return;
  434.     }
  435.  
  436.     while (nDataLen)
  437.     {
  438.         if (nBytes < sizeof(short) * 4)
  439.         {
  440.             nToCopy = sizeof(short) * 4 - nBytes;
  441.             if (nToCopy > nDataLen)
  442.                 nToCopy = nDataLen;
  443.             memcpy((char *) &pkt + nBytes, pvData, nToCopy);
  444.             pvData = (char *) pvData + nToCopy;
  445.             nDataLen -= nToCopy;
  446.             nBytes += nToCopy;
  447.         }
  448.         if (nBytes < sizeof(short) * 4)
  449.             break;
  450.         pt = (enum packet_type) ntohs(pkt.nType);
  451.         iLen = ntohs(pkt.iPacketLen);
  452.         nCRC = ntohs(pkt.nCRC);
  453.         id = ntohs(pkt.iPacketID);
  454.         if (iLen > PACKET_MAX || iLen < 0) /* Sanity check */
  455.         {
  456.             nBytes = 0;
  457.             nDataLen = 0;
  458.             KillReceiveTimeout();
  459.             if (ppqList)
  460.                 KillTransmitTimeout();
  461.             FlushInput();
  462.             if (ppqList)
  463.                 SetTransmitTimeout();
  464.             return;
  465.         }
  466.         if (nBytes < sizeof(short) * 4 + iLen)
  467.         {
  468.             nToCopy = sizeof(short) * 4 + iLen - nBytes;
  469.             if (nDataLen < nToCopy)
  470.                 nToCopy = nDataLen;
  471.             memcpy((char *) &pkt + nBytes, pvData, nToCopy);
  472.             pvData = (char *) pvData + nToCopy;
  473.             nDataLen -= nToCopy;
  474.             nBytes += nToCopy;
  475.         }
  476.         if (nBytes == sizeof(short) * 4 + iLen)
  477.         {
  478.             nBytes = 0;
  479.             pkt.nCRC = 0;
  480.             if (CalcCRC(&pkt, iLen + sizeof(short) * 4) == nCRC)
  481.             {
  482.                 switch(pt)
  483.                 {
  484.                 case PT_Data:
  485.                     iLocation = nInSeq - id;
  486.                     TransmitAck(id);
  487.                     if (iLocation <= 0)
  488.                         InsertIntoIncoming(&pkt, iLen + sizeof(short) * 4);
  489.                     break;
  490.  
  491.                 case PT_Nak:
  492.                     if (ppqList &&
  493.                         id == ppqList->idPacket)
  494.                         TransmitHead();
  495.                     break;
  496.  
  497.                 case PT_Ack:
  498.                     AckReceived(id);
  499.                     break;
  500.  
  501.                 case PT_Shutdown:
  502.                     Shutdown(0);
  503.                     break;
  504.                 }
  505.             }
  506.             else
  507.             {
  508.                 /* If we flush input we should also
  509.                  * reset any tranmit timeout, otherwise
  510.                  * we may resend the packet while flushing,
  511.                  * and flush the Ack. We also kill any
  512.                  * receive timeout because we have already
  513.                  * "flushed" any existing input.
  514.                  */
  515.                 KillReceiveTimeout();
  516.                 if (ppqList)
  517.                     KillTransmitTimeout();
  518.                 FlushInput();
  519.                 if (ppqList)
  520.                     SetTransmitTimeout();
  521.                 return;
  522.             }
  523.         }
  524.     }
  525.     if (nBytes)
  526.         SetReceiveTimeout();
  527. }
  528.  
  529. void    PacketReceiveData(void *pvData, int nDataLen)
  530. {
  531.     static    int    nBits = 0;
  532.     static    char    c = 0;
  533.     static    int    nCtlX = 0;
  534.     char    cIn;
  535.     char    cTmp;
  536.     int    nBitsLeft = 0;
  537.     int    iOut = 0;
  538.     int    nBitsNow;
  539.     char    *pchDataOut;
  540.     char    *pchDataIn;
  541.  
  542.     if (!pvData)
  543.     {
  544.         ProcessData(0, nDataLen);
  545.         nBits = nBitsLeft = 0;
  546.         return;
  547.     }
  548.  
  549.     KillReceiveTimeout();
  550.  
  551.     pchDataIn = (char *) pvData;
  552.     pchDataOut = (char *) malloc(nDataLen);
  553.     while (nDataLen || nBitsLeft)
  554.     {
  555.         if (nBitsLeft)
  556.         {
  557.             nBitsNow = 8 - nBits;
  558.             if (nBitsLeft < nBitsNow)
  559.                 nBitsNow = nBitsLeft;
  560.             c <<= nBitsNow;
  561.             cTmp = cIn >> (nBitsLeft - nBitsNow);
  562.             cTmp &= ((1 << nBitsNow) - 1);
  563.             c |= cTmp;
  564.             nBits += nBitsNow;
  565.             nBitsLeft -= nBitsNow;
  566.             if (nBits == 8)
  567.             {
  568.                 pchDataOut[iOut++] = c;
  569.                 nBits = 0;
  570.             }
  571.         }
  572.         else
  573.         {
  574.             cIn = *pchDataIn++;
  575.             nDataLen--;
  576.             if (cIn == '\030') /* ^X */
  577.             {
  578.                 nCtlX++;
  579.                 if (nCtlX >= 5)
  580.                     Shutdown();
  581.                 continue;
  582.             }
  583.             else
  584.             {
  585.                 nCtlX = 0;
  586.             }
  587.             if (cIn == '@')
  588.             {
  589.                 cIn = c = 0;
  590.                 nBitsLeft = 0;
  591.                 nBits = 0;
  592.             }
  593.             else
  594.             {
  595.                 if (cIn >= 'A' && cIn <= 'Z')
  596.                     cIn -= 'A';
  597.                 else if (cIn >= 'a' && cIn <= 'z')
  598.                     cIn = cIn - 'a' + 26;
  599.                 else if (cIn >= '0' && cIn <= '9')
  600.                     cIn = cIn - '0' + 52;
  601.                 else if (cIn == '.')
  602.                     cIn = 62;
  603.                 else if (cIn == '/')
  604.                     cIn = 63;
  605.                 else
  606.                     continue;
  607.                 nBitsLeft = 6;
  608.             }
  609.         }
  610.     }
  611.     ProcessData(pchDataOut, iOut);
  612.     free(pchDataOut);
  613. }
  614.  
  615. void    PacketTransmitData(void *pvData, int iDataLen, int iStream)
  616. {
  617.     int    iFlags = PQF_LEADER;
  618.  
  619.     while (iDataLen > PACKET_MAX)
  620.     {
  621.         SendPacket(pvData, PACKET_MAX, iStream, iFlags);
  622.         pvData = (char *) pvData + PACKET_MAX;
  623.         iDataLen -= PACKET_MAX;
  624.         iFlags = 0;
  625.     }
  626.     iFlags |= PQF_TRAILER;
  627.     SendPacket(pvData, iDataLen, iStream, iFlags);
  628. }
  629.  
  630.  
  631. void
  632. ReInitPackets(void)
  633. {
  634.     int    i;
  635.  
  636.     nInSeq = nOutSeq = 0;
  637.     for (i = 0; i < MAX_STREAMS; i++)
  638.         FlushQueue(appqStreams + i);
  639.     FlushQueue(&ppqList);
  640.     memset(aiStreams, 0, sizeof(aiStreams));
  641. }
  642.